package net.oschina.bilbodai.common.beanutil.bean.code;

import net.oschina.bilbodai.common.beanutil.bean.BeanDumpUtil;
import net.oschina.bilbodai.common.beanutil.bean.IBeanAccessor;
import net.oschina.bilbodai.common.beanutil.bean.core.PropertyDumpInfo;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Type;

import static org.objectweb.asm.Opcodes.ACONST_NULL;
import static org.objectweb.asm.Opcodes.CHECKCAST;
import static org.objectweb.asm.Opcodes.INVOKEINTERFACE;

/**
 * @author daimao  Date: 16/5/28 Time: 下午4:34
 * @version $Id$
 */
public class SingleToSingleApplier extends DumpOverrideAwareApplier {

    public SingleToSingleApplier(PropertyDumpInfo dumpInfo) {
        super(dumpInfo);
    }

    @Override
    protected void loadSrcCastPropertyOntoStack(MethodVisitor mv) {
        loadSrcCastPropertyOntoStack0(mv);
    }

    @Override
    protected void doApply(MethodVisitor mv) {
        invokeCreateBeanAccessorAndStoreLocal(mv, dumpInfo.getSrcField().getType(), dumpInfo.getTargetField().getType());
        loadTargetCastOntoStack0(mv);
        localAccessorOntoStack(mv);
        loadSrcCastPropertyOntoStack(mv);
        mv.visitInsn(ACONST_NULL);
        mv.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(IBeanAccessor.class), BeanDumpUtil.PROPERTY_DUMP_METHOD.getName(), Type.getMethodDescriptor(BeanDumpUtil.PROPERTY_DUMP_METHOD), true);
        mv.visitTypeInsn(CHECKCAST,dumpInfo.getTargetFieldInternalName());
        invokeTargetPropertySetter0(mv);
    }

}